package com.cxyd.modules.wms.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cxyd.common.Utils.BeanUtils;
import com.cxyd.common.exception.RootException;
import com.cxyd.common.page.PageData;
import com.cxyd.common.service.impl.CrudServiceImpl;
import com.cxyd.modules.sys.dto.SysUserDTO;
import com.cxyd.modules.sys.service.SysUserService;
import com.cxyd.modules.wms.dao.SpuDao;
import com.cxyd.modules.wms.dto.SpuDTO;
import com.cxyd.modules.wms.entity.SpuEntity;
import com.cxyd.modules.wms.entity.StockEntity;
import com.cxyd.modules.wms.entity.ZoneEntity;
import com.cxyd.modules.wms.excel.ImportSpuExcel;
import com.cxyd.modules.wms.excel.ImportStockExcel;
import com.cxyd.modules.wms.service.SpuService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品信息
 *
 * @author g_Cycle gengruyi01@163.com
 * @since 1.0.0 2023-04-27
 */
@Service
public class SpuServiceImpl extends CrudServiceImpl<SpuDao, SpuEntity, SpuDTO> implements SpuService {
    private final SysUserService userService;

    public SpuServiceImpl(SysUserService userService) {
        this.userService = userService;
    }

    @Override
    public PageData<SpuDTO> page(Map<String, Object> params) {
        //1.查询物料信息
        final IPage<SpuEntity> page = baseDao.selectViewPage(
                getPage(params, "spu_id", true),
                getWrapper(params)
        );

        return getPageData(page, SpuDTO.class);
    }

    @Override
    public QueryWrapper<SpuEntity> getWrapper(Map<String, Object> params) {
        //查询条件
        String spuNo = (String) params.get("spuNo");
        String spuName = (String) params.get("spuName");
        String spuSpec = (String) params.get("spuSpec");

        QueryWrapper<SpuEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("s1.status", 0);
        wrapper.like(StringUtils.isNotBlank(spuNo), "s1.spu_no", spuNo);
        wrapper.like(StringUtils.isNotBlank(spuName), "s1.spu_name", spuName);
        wrapper.like(StringUtils.isNotBlank(spuSpec), "s1.spu_spec", spuSpec);
        return wrapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(@RequestBody Long[] ids) {
        for (int i = 0; i < ids.length; i++) {
            deleteByLocateId(ids[i]);
        }
    }

    @Override
    public SpuEntity findBySpuNo(String spuNo) {
        QueryWrapper<SpuEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(SpuEntity::getSpuNo, spuNo);
        return baseDao.selectOne(qw);
    }

    @Override
    public SpuEntity getSpuBySpuNo(String spuNo) {
        QueryWrapper<SpuEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(SpuEntity::getSpuNo, spuNo);
        return baseDao.selectOne(qw);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int extractionData(MultipartFile file) {
        // 1. 校验文件
        List<ImportSpuExcel> list = null;
        try {
            if (file.isEmpty()) {
                throw new RuntimeException("上传文件不能为空");
            }
            String filename = file.getOriginalFilename();
            if (!filename.endsWith(".xls") && !filename.endsWith(".xlsx")) {
                throw new RuntimeException("仅支持 Excel 文件");
            }

            // 2. 解析 Excel
            ImportParams params = new ImportParams();
            params.setTitleRows(0); // 标题行占0行
            params.setHeadRows(1);  // 表头占1行
            list = ExcelImportUtil.importExcel(
                    file.getInputStream(),
                    ImportSpuExcel.class,
                    params
            );
        } catch (IOException e) {
            throw new RuntimeException("文件读取失败: " + e.getMessage(), e);
        } catch (Exception e) {
            throw new RuntimeException("Excel 解析失败: " + e.getMessage(), e);
        }
        // 过滤掉所有字段都为 null 的数据行
        list = list.stream()
                .filter(item -> {
                    // 检查对象的所有字段是否都为 null
                    return Arrays.stream(item.getClass().getDeclaredFields())
                            .anyMatch(field -> {
                                try {
                                    field.setAccessible(true);
                                    return field.get(item) != null;
                                } catch (IllegalAccessException e) {
                                    return false;
                                }
                            });
                })
                .collect(Collectors.toList());

        if (list.size() == 0) {
            throw new RuntimeException("导入数据为空！");
        }
        // 3. 数据校验和保存
        int count = 0;
        for (ImportSpuExcel excel : list) {
            // 1. 数据校验（示例）
            if (StrUtil.isEmpty(excel.getSpuNo())) {
                throw new RuntimeException("物料编号不能为空！");
            }
            if (StrUtil.isEmpty(excel.getSpuName())) {
                throw new RuntimeException("物料名称不能为空！");
            }

            // 2. 转换为实体对象（假设 SpuEntity 是数据库实体）
            SpuEntity spu = convertToEntity(excel);
            // 3. 保存或更新
            if (spu.getSpuId() != null) {
                baseDao.updateById(spu);
            } else {
                baseDao.insert(spu);
            }
            count++;
        }
        return count;
    }

    private SpuEntity convertToEntity(ImportSpuExcel excel) {
        SpuEntity spu = new SpuEntity();
        BeanUtils.copyProperties(excel, spu);
        return spu;
    }

    public void deleteByLocateId(Long id) {
        baseDao.deleteById(id);
    }
}